/* 
 * File:   PriorityList.h
 * Author: Muqtafi Akhmad
 */
#include "../Utilities/boolean.h"
#include "../ADTDateTime/DateTime.h"
#include "../ADTEvent/Event.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// macro definition for priority list element attribute access
#ifndef PRIORITY_LIST_H
#define	PRIORITY_LIST_H
#define Info(P) (P)->info
#define Prev(P) (P)->prev
#define Next(P) (P)->next
#define First(L) ((L).First)
#define Last(L) ((L).Last)
#define NbElement(L) ((L).elementCount)
// type of element, that is Event
typedef Event infotype;
// definition of priority list element that contains event
typedef struct tElmtEvent *EventAddr;

typedef struct tElmtEvent {
    infotype info; // the event
    EventAddr prev; // pointer to the previous element
    EventAddr next; // pointer to the next element
} ElmtEvent;
// definition of priority list

typedef struct {
    int elementCount;
    EventAddr First; // pointer to the first element
    EventAddr Last; // pointer to the next element
} EventList;
/**
 * Returns true if the list is empty
 * @param L list
 * @return boolean is list empty
 */
boolean EventListEmpty(EventList L);
/**
 * Creates an empty list
 * @param L list
 */
void CreateEventList(EventList * L);
/**
 * Allocate a list element for the given event
 * Returns NULL if allocation failed
 * @param X event
 * @return address to the list element
 */
EventAddr Alokasi(infotype X);
/**
 * Returns address of list element that contains event with 
 * the given entry number
 * @param L list
 * @param entryNo entry number
 * @return address to list element
 */
EventAddr SearchEventByEntryNo(EventList L, long entryNo);
/**
 * Returns address of the first event that matches the date time
 * Elements scanned start from the start pointer
 * @param L list
 * @param start the start pointer, NULL to search from the beginning
 * @param dateTime date time
 * @return address to list element
 */
EventAddr SearchFirstEvent(EventList L, EventAddr start, DateTime dateTime);
/**
 * Insert a new event ordered ascending by date time
 * @param L list
 * @param X elment
 */
void InsertEvent(EventList *L, infotype X);
/**
 * Delete an event from list by the event number
 * @param L list
 * @param entryNo entry number
 */
void DeleteEvent(EventList *L, long entryNo);
/**
 * Deallocate the entire elements in the list
 * @param L list
 */
void Dealokasi(EventList* L);
void InsertBefore(EventList *L, EventAddr P, EventAddr Next);
/**
 * Insert a new list element as the next of prec element
 * @param L list 
 * @param P address of inserted element
 * @param Prec address of previous element
 */
void InsertAfter(EventList * L, EventAddr P, EventAddr Prec);
/**
 * Print event in the list element
 * @param L list
 */
void PrintInfo(EventList L);
/**
 * Insert element as the first element of list
 * @param L list
 * @param P address of element
 */
void InsertFirst(EventList* L, EventAddr P);
/**
 * Insert element as the last element of list
 * @param L list
 * @param P address of element
 */
void InsertLast (EventList * L, EventAddr P);
/**
 * Dealloc a list element
 * @param ptr pointer to the element
 */
void DeleteElement(EventList* L, EventAddr ptr);
/**
 * Returns the address of n-th list element from the tail of list
 * @param n the order element from behind
 * @return element address
 */
EventAddr GetLastNAddress(EventList L, int n);

/**
 * Get event given the date, and store them in the array of id
 * @param L EventList
 * @param d Date associated
 * @param id array of entryID
 * @param size_t length of id
 * @return length of entryId found
 */
int GetEventCountInDay(EventList L, DateTime d, long* id, int size_t);

#endif

